import os
import sys
import wx
import ogre.renderer.OGRE as ogre 


try:
	from agw import aui
	from agw import flatmenu as FM
	from agw.fmresources import FM_OPT_SHOW_CUSTOMIZE, FM_OPT_SHOW_TOOLBAR, FM_OPT_MINIBAR
except ImportError: # if it's not there locally, try the wxPython lib.
	import wx.lib.agw.aui as aui
	import wx.lib.agw.flatmenu as FM
	from wx.lib.agw.fmresources import FM_OPT_SHOW_CUSTOMIZE, FM_OPT_SHOW_TOOLBAR, FM_OPT_MINIBAR


##
#try:
#    dirName = os.path.dirname(os.path.abspath(__file__))
#except:
dirName = os.path.dirname(os.path.abspath(sys.argv[0]))

bitmapDir = os.path.join(dirName, 'bitmaps')
sys.path.append(os.path.split(dirName)[0])




class Plugin:
	
	def __init__(self,frame):
		self.Selector = frame.plugins.SceneSelectorPlugin
		self.CameraPlugin = frame.plugins.CameraPlugin
		
		c = self._createCtrls(frame)

		
		frame.getAuiManager().AddPane(c, aui.AuiPaneInfo().
					  Name("SceneTree").Caption("Scene Tree Pane").
					  Left().Layer(1).Position(1).CloseButton(False).MaximizeButton(True).MinimizeButton(True))

		#
		self.updateTree()
		pass
	
	##
	def _createMiniToolbar(self,parent):
	
		# create mini toolbar
		mtb = FM.FlatMenuBar(parent, wx.ID_ANY,16, 6, options = FM_OPT_SHOW_TOOLBAR|FM_OPT_MINIBAR)
	
		checkCancelBmp = wx.Bitmap(os.path.join(bitmapDir, "ok-16.png"), wx.BITMAP_TYPE_PNG)
		viewMagBmp = wx.Bitmap(os.path.join(bitmapDir, "viewmag-16.png"), wx.BITMAP_TYPE_PNG)
		viewMagFitBmp = wx.Bitmap(os.path.join(bitmapDir, "viewmagfit-16.png"), wx.BITMAP_TYPE_PNG)
		viewMagZoomBmp = wx.Bitmap(os.path.join(bitmapDir, "viewmag-p-16.png"), wx.BITMAP_TYPE_PNG)
		viewMagZoomOutBmp = wx.Bitmap(os.path.join(bitmapDir, "viewmag-m-16.png"), wx.BITMAP_TYPE_PNG)
	
		mtb.AddCheckTool(wx.ID_ANY, "Check Settings Item", checkCancelBmp)
		mtb.AddCheckTool(wx.ID_ANY, "Check Info Item", checkCancelBmp)
		mtb.AddSeparator()
		mtb.AddRadioTool(wx.ID_ANY, "Magnifier", viewMagBmp)
		mtb.AddRadioTool(wx.ID_ANY, "Fit", viewMagFitBmp)
		mtb.AddRadioTool(wx.ID_ANY, "Zoom In", viewMagZoomBmp)
		mtb.AddRadioTool(wx.ID_ANY, "Zoom Out", viewMagZoomOutBmp)

		return mtb

	##
	def _createTreeCtrl(self,parent):

		tree = wx.TreeCtrl(parent, -1, wx.Point(0, 0), wx.Size(240, 250),
						   wx.TR_DEFAULT_STYLE | wx.NO_BORDER)

		imglist = wx.ImageList(16, 16, True, 2)
		imglist.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, wx.Size(16,16)))
		imglist.Add(wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, wx.Size(16,16)))
		tree.AssignImageList(imglist)

		def OnCompareItems(self, item1, item2):
			t1 = self.GetItemText(item1)
			t2 = self.GetItemText(item2)
			self.log.WriteText('compare: ' + t1 + ' <> ' + t2 + '\n')
			if t1 < t2: return -1
			if t1 == t2: return 0
			return 1
		tree.OnCompareItems = OnCompareItems

		tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
		tree.Bind(wx.EVT_KEY_UP, self._KeyUpEventListener)
		tree.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)

		self.KeyUpListeners = []
		self.KeyUpListeners.append(self.OnDeleteItem)
		return tree;

	def addKeyUpListener(self,l): 
		self.KeyUpListeners.append(l)
		pass

	def removeKeyUpListener(self,l): 
		self.KeyUpListeners.remove(l)
		pass
	
	def _KeyUpEventListener(self,event): 
		for l in self.KeyUpListeners:
			l(event)
			if event.GetSkipped() :
				return
		pass

	def OnLeftDClick(self,event):
		pt = event.GetPosition();
		item, flags = self.treeCtrl.HitTest(pt)
		if item :
			sn = self._selcet(item)
			if sn:
				self.CameraPlugin.getCamera().lookAt(sn._getDerivedPosition())
		pass
	
	def OnSelChanged(self,event):
		item = event.GetItem()
		if item:
			self._selcet(item)
		event.Skip()
		pass

	def _msg_is_delete(self,s):

		dlg = wx.MessageDialog(self.treeCtrl, 'Are you sure to delete ' + s,
		                       'A Message Box',
		                       wx.YES_NO | wx.ICON_INFORMATION | wx.NO_DEFAULT
		                       #wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION
		                       )
		is_yes = dlg.ShowModal()
		dlg.Destroy()
		return is_yes == wx.ID_YES
	
	def OnDeleteItem(self,event):
		kc = event.GetKeyCode()
		if kc == wx.WXK_DELETE:#delete
			event.Skip()
			
			item = self.treeCtrl.GetSelection()
			if item:
				data = self.treeCtrl.GetItemData(item)
				if data :
					data = data.Data
					
					if type(data) == ogre.Node :
						if self._msg_is_delete('Node '+ '<' + data.getName() + '>'):
							data.getParent().removeChild(data)
							self.treeCtrl.Delete(item)
						pass
					
					elif type(data) == ogre.SceneNode :
						if self._msg_is_delete('SceneNode '+ '<'+ data.getName() + '>'):
							if data.getParent() != None :
								data.getParent().removeChild(data)
								self.treeCtrl.Delete(item)
						pass
					
					elif type(data) == ogre.MovableObject \
					or   type(data) == ogre.Entity\
					or   type(data) == ogre.BillboardChain\
					or   type(data) == ogre.BillboardSet\
					or   type(data) == ogre.Frustum\
					or   type(data) == ogre.Camera\
					or   type(data) == ogre.Light\
					or   type(data) == ogre.ManualObject\
					or   type(data) == ogre.MovablePlane\
					or   type(data) == ogre.ParticleSystem :
						if self._msg_is_delete(data.getMovableType()+' '+ '<' + data.getName() + '>'):
							data.detachFromParent()
							self.treeCtrl.Delete(item)
						pass
					
					#elif type(data) == ogre.SimpleRenderable\
					#or   type(data) == ogre.Region\
					#or   type(data) == ogre.BatchInstance :
					#	assert(False)
					#	pass
					
					else :
						pass
		pass

	def _selcet(self,item):
		print self.treeCtrl.GetItemText(item)
		data = self.treeCtrl.GetItemData(item)
		if data :
			data = data.Data
			#print data.Data
			if type(data) == ogre.Node :
				self.Selector.setCurrSelectNode(data.castAsSceneNode())
				return data.castAsSceneNode()
			if type(data) == ogre.SceneNode :
				self.Selector.setCurrSelectNode(data)
				return data
			elif type(data) == ogre.MovableObject \
			or   type(data) == ogre.Entity\
			or   type(data) == ogre.BillboardChain\
			or   type(data) == ogre.BillboardSet\
			or   type(data) == ogre.Frustum\
			or   type(data) == ogre.Camera\
			or   type(data) == ogre.Light\
			or   type(data) == ogre.ManualObject\
			or   type(data) == ogre.MovablePlane\
			or   type(data) == ogre.ParticleSystem :
				self.Selector.setCurrSelect(data)
				self.Selector.setCurrSelectNode(data.getParentSceneNode())
				return data.getParentSceneNode()
			#elif type(data) == ogre.SimpleRenderable\
			#or   type(data) == ogre.Region\
			#or   type(data) == ogre.BatchInstance :
			#	assert(False)
			#	pass
			else :
				self.Selector.setCurrSelect(data)

		return None
	##
	def _createCtrls(self,parent):
		##
		panel = wx.Panel(parent, -1, wx.Point(0, 0), wx.Size(160, 250),
						   wx.TR_DEFAULT_STYLE | wx.NO_BORDER)
	
		##
		mtb = self._createMiniToolbar(panel)
		self.treeCtrl = self._createTreeCtrl(panel)
	
		##
		miniSizer = wx.BoxSizer(wx.VERTICAL)
		miniSizer.Add(mtb, 0, wx.EXPAND)
		miniSizer.Add(self.treeCtrl, 1, wx.EXPAND)
		panel.SetSizer(miniSizer)
		return panel

	def getTreeCtrl(self):
		return self.treeCtrl
	
	def updateTree(self):
		def tid(d):
			data = wx.TreeItemData()
			data.SetData(d)
			return data
		#data=tid()

		treeCtrl = self.treeCtrl
		treeCtrl.DeleteAllItems()
		

		ogreroot = ogre.Root.getSingleton()

		if ogreroot == None:
			return


		wxroot = treeCtrl.AddRoot("Root",data=tid(ogreroot))#,data=tid(ogreroot)
		
		##
		for sm in ogreroot.getSceneManagerIterator():
			wxSMnode = treeCtrl.AppendItem(wxroot, sm.getName(), 0,data=tid(sm))#,data=tid(sm)
			self._updateSceneTree(treeCtrl,wxSMnode,sm.getRootSceneNode())
	
			for mof in ogreroot.getMovableObjectFactoryIterator():
				wxMOnode = treeCtrl.AppendItem(wxSMnode, mof.getType()+'s', 0,data=tid(mof))
				for mo in sm.getMovableObjectIterator(mof.getType()):
					treeCtrl.AppendItem(wxMOnode, mo.getName(), 1,data=tid(mo))#,data=tid(mo)
	
			wxCAnode = treeCtrl.AppendItem(wxSMnode, 'Cameras', 0)
			for ca in sm.getCameraIterator():
				treeCtrl.AppendItem(wxCAnode, ca.getName(), 1,data=tid(ca))#,data=tid(ca)
	
			wxANnode = treeCtrl.AppendItem(wxSMnode, 'Animations', 0)
			for an in sm.getAnimationIterator():
				treeCtrl.AppendItem(wxANnode, an.getName(), 1,data=tid(an))#,data=tid(an)
	
		##
		# wxAnode = treeCtrl.AppendItem(wxroot, 'ArchiveManager', 0)
		# for ar in ogre.ArchiveManager.getSingleton().getArchiveIterator():
			# treeCtrl.AppendItem(wxAnode, ar.getName(), 1)
	
		##
		# wxManode = treeCtrl.AppendItem(wxroot, 'MaterialManager', 0)
		# for ma in ogre.MaterialManager.getSingleton().getResourceIterator():
			# treeCtrl.AppendItem(wxManode, ma.getName(), 1)
	
		##
		# wxMenode = treeCtrl.AppendItem(wxroot, 'MeshManager', 0)
		# for me in ogre.MeshManager.getSingleton().getResourceIterator():
			# treeCtrl.AppendItem(wxMenode, me.getName(), 1)
	
		##
		wxPSMnode = treeCtrl.AppendItem(wxroot, 'ParticleSystemManager', 0,data=tid(ogre.ParticleSystemManager.getSingleton()))#,data=tid(ogre.ParticleSystemManager.getSingleton())
	
		wxAFnode = treeCtrl.AppendItem(wxPSMnode, 'AffectorFactorys', 0)
		for af in ogre.ParticleSystemManager.getSingleton().getAffectorFactoryIterator():
			treeCtrl.AppendItem(wxAFnode, af.getName(), 1, data=tid(af))#, data=tid(af)
	
		wxEFnode = treeCtrl.AppendItem(wxPSMnode, 'EmitterFactorys', 0)
		for ef in ogre.ParticleSystemManager.getSingleton().getEmitterFactoryIterator():
			treeCtrl.AppendItem(wxEFnode, ef.getName(), 1, data=tid(ef))#, data=tid(ef)
	
		wxRFnode = treeCtrl.AppendItem(wxPSMnode, 'RendererFactorys', 0)
		for rf in ogre.ParticleSystemManager.getSingleton().getRendererFactoryIterator():
			treeCtrl.AppendItem(wxRFnode, rf.getType(), 1, data=tid(rf))#, data=tid(rf)
	
		wxPSTnode = treeCtrl.AppendItem(wxPSMnode, 'ParticleSystemTemplates', 0)
		for pst in ogre.ParticleSystemManager.getSingleton().getTemplateIterator():
			treeCtrl.AppendItem(wxPSTnode, pst.getName(), 1, data=tid(pst))#, data=tid(pst)
	
		##
		# wxSMnode = treeCtrl.AppendItem(wxroot, 'SkeletonManager', 0)
		# for sm in ogre.SkeletonManager.getSingleton().getResourceIterator():
			# treeCtrl.AppendItem(wxSMnode, sm.getName(), 1)
	
		##
		wxOMnode = treeCtrl.AppendItem(wxroot, 'OverlayManager', 0, data=tid(ogre.OverlayManager.getSingleton()))#, data=tid(ogre.OverlayManager.getSingleton())
		wxOvnode = treeCtrl.AppendItem(wxOMnode, 'Overlays', 0)
		for Ov in ogre.OverlayManager.getSingleton().getOverlayIterator():
			treeCtrl.AppendItem(wxOvnode, Ov.getName(), 1, data=tid(Ov))#, data=tid(Ov)
	
		wxTenode = treeCtrl.AppendItem(wxOMnode, 'Templates', 0)
		for Te in ogre.OverlayManager.getSingleton().getTemplateIterator():
			treeCtrl.AppendItem(wxTenode, Te.getName(), 1, data=tid(Te))#, data=tid(Te)
	
		##
		# wxFMnode = treeCtrl.AppendItem(wxroot, 'FontManager', 0)
		# for fo in ogre.FontManager.getSingleton().getResourceIterator():
			# treeCtrl.AppendItem(wxFMnode, fo.getName(), 1)
	
	
		wxRGMnode = treeCtrl.AppendItem(wxroot, 'ResourceGroupManager', 0, data=tid(ogre.ResourceGroupManager.getSingleton()))#, data=tid(ogre.ResourceGroupManager.getSingleton())
		it = ogre.ResourceGroupManager.getSingleton().getResourceManagerIterator()
		while it.hasMoreElements():
			k = it.peekNextKey()
			v = it.peekNextValue()
	
			rmnode = treeCtrl.AppendItem(wxRGMnode, k, 0)
			for r in v.getResourceIterator():
				treeCtrl.AppendItem(rmnode, r.getName(), 1, data=tid(r))#, data=tid(r)
	
			it.moveNext()
	
		rgnode = treeCtrl.AppendItem(wxRGMnode, 'ResourceGroups', 0)
		for rg in ogre.ResourceGroupManager.getSingleton().getResourceGroups():
			rdnode = treeCtrl.AppendItem(rgnode, rg, 0)
			# for rn in ogre.ResourceGroupManager.getSingleton().listResourceNames(rg):
				# treeCtrl.AppendItem(rdnode, rn, 1)
			for rl in ogre.ResourceGroupManager.getSingleton().getResourceLocationList(rg):
				arnode = treeCtrl.AppendItem(rdnode, rl.archive.getName(), 0, data=tid(rl.archive))#, data=tid(rl.archive)
				for f in rl.archive.list():
					treeCtrl.AppendItem(arnode, f, 1, data=tid(f))
			# for rl in ogre.ResourceGroupManager.getSingleton().listResourceLocations(rg):
				# treeCtrl.AppendItem(rdnode, rl, 1)
	
		##
		lsmnode = treeCtrl.AppendItem(wxroot, 'LodStrategyManager', 0, data=tid(ogre.LodStrategyManager.getSingleton()))#, data=tid(ogre.LodStrategyManager.getSingleton())
		for ls in ogre.LodStrategyManager.getSingleton().getIterator():
			arnode = treeCtrl.AppendItem(lsmnode, ls.getName(), 1, data=tid(ls))
	
		pass
	
	
	def _updateSceneTree(self,treeCtrl,wxParentNode,parentNode):
		nd = wx.TreeItemData()
		nd.SetData(parentNode)
		wxnode = treeCtrl.AppendItem(wxParentNode, parentNode.getName(), 0, data=nd)
		for mo in parentNode.castAsSceneNode().getAttachedObjectIterator():
			md = wx.TreeItemData()
			md.SetData(mo)
			wxmo = treeCtrl.AppendItem(wxnode, mo.getName(), 1, data=md)

		for cn in parentNode.getChildIterator():
			self._updateSceneTree(treeCtrl,wxnode,cn)
		pass

	def IHelp(self):
		return """key delete to delete the select"""

	def IUpdateScene(self):
		self.updateTree()
		pass

	def IEndLoadScene(self):
		self.updateTree()
		pass
	
	def IClearScene(self):
		self.updateTree()
		pass

	def IShutdowm(self):
		self.treeCtrl.DeleteAllItems()
		pass
	
##
def IInit(frame):
	return Plugin(frame)
